package org.example;

import lombok.Data;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class LogExtractor {


    public static Map<String, String> processorMap = new LinkedHashMap<>();

    public static final DateTimeFormatter FORMATTER =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    static {
        // 从配置文件加载处理器映射关系
        try (InputStream input = LogExtractor.class.getClassLoader().getResourceAsStream("processor.properties")) {
            Properties prop = new Properties();
            prop.load(input);
            
            for (String key : prop.stringPropertyNames()) {
                processorMap.put(key, prop.getProperty(key));
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 如果配置文件加载失败，使用默认配置
            initDefaultProcessorMap();
        }
    }
    
    private static void initDefaultProcessorMap() {
        processorMap.put("IntentionRecognitionProcessor", "意图分类");
        processorMap.put("AsyncRecommendationProcessor", "推荐问题");
        processorMap.put("UnderstandProcessor", "问题生成理解");
        processorMap.put("EntityExtractionProcessor", "实体抽取");
        processorMap.put("RewriteProcessor", "查询改写");
        processorMap.put("ThinkingProcessor", "思考过程");
        processorMap.put("TextToSqlProcessor", "textToSql");
        processorMap.put("GenerateSummaryProcessor", "生成总结");
        processorMap.put("ResultSummaryProcessor", "结果汇总");
        processorMap.put("SlotFillingProcessor", "预警抽槽");
        processorMap.put("DeepAttributionProcessor", "深度归因");
        processorMap.put("RecommendationProcessor", "推荐问题");
        processorMap.put("ExpertProcessor", "行业大家");
        processorMap.put("TOTAL", "总耗时");
    }

    @Data
    public static class LogInfo {
        private long logTime;
        private String sessionId;
        private String messageId;
        private String currentProcessor;
        private String businessType;
        private String logId;
        private String userId;
        private String domainId;
        private String subjectId;
        private String url;
        private String requestBody;
        private String outputData;
        private String rt;
    }

    private static final Pattern CURRENT_PROCESSOR_PATTERN = Pattern.compile("currentProcessor=([^,|]+)");
    private static final Pattern BUSINESS_TYPE_PATTERN = Pattern.compile("bussinessType=([^,|]+)");
    private static final Pattern SESSION_ID_PATTERN = Pattern.compile("sessionId=([^,|]+)");
    private static final Pattern LOG_ID_PATTERN = Pattern.compile("logId=([^,|]+)");
    private static final Pattern USER_ID_PATTERN = Pattern.compile("userId=([^,|]+)");
    private static final Pattern DOMAIN_ID_PATTERN = Pattern.compile("domainId=([^,|]+)");
    private static final Pattern SUBJECT_ID_PATTERN = Pattern.compile("subjectId=([^,|]+)");
    private static final Pattern MESSAGE_ID_PATTERN = Pattern.compile("messageId=([^,|]+)");
    private static final Pattern URL_PATTERN = Pattern.compile("url=([^,|]+)");
    private static final Pattern REQUEST_BODY_PATTERN = Pattern.compile("requestBody=([^|]+).*?");
    private static final Pattern OUTPUT_DATA_PATTERN = Pattern.compile("outputData=(.*?)(?=\\s+\\||$)");
    private static final Pattern RT_PATTERN = Pattern.compile("rt=([^,|]+)");


    // 新增方法：解析所有日志信息
    public static List<LogInfo> extractAllLogInfo(String filePath) throws IOException {
        List<LogInfo> result = new ArrayList<>();

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "UTF-8"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.contains("currentProcessor=")) {
                    LogInfo extractedInfo = processLine(line);
                    if (extractedInfo != null) {
                        result.add(extractedInfo);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 按processorMap集合的key顺序来排
        // 创建一个映射，将processor名称映射到其在processorMap中的顺序
        Map<String, Integer> processorOrder = new LinkedHashMap<>();
        int index = 0;
        for (String key : processorMap.keySet()) {
            processorOrder.put(key, index++);
        }

        return result.stream()
                .sorted(Comparator.comparingInt(logInfo -> {
                    String currentProcessor = logInfo.getCurrentProcessor();
                    // 获取currentProcessor在processorMap中的索引顺序
                    return processorOrder.getOrDefault(currentProcessor, Integer.MAX_VALUE);
                }))
                .collect(Collectors.toList());
    }



    private static LogInfo processLine(String line) {
        try {
            // 提取所有字段
            LocalDateTime logTime = LocalDateTime.parse(line.substring(0, 23), FORMATTER);

            String sessionId = extractFieldValue(line, SESSION_ID_PATTERN);

            String currentProcessor = extractFieldValue(line, CURRENT_PROCESSOR_PATTERN);
            String businessType = extractFieldValue(line, BUSINESS_TYPE_PATTERN);
            if (businessType == null) {
                businessType = extractFieldValue(line, Pattern.compile("businessType=([^,}]+)"));
            }
            String logId = extractFieldValue(line, LOG_ID_PATTERN);
            String userId = extractFieldValue(line, USER_ID_PATTERN);
            String domainId = extractFieldValue(line, DOMAIN_ID_PATTERN);
            String subjectId = extractFieldValue(line, SUBJECT_ID_PATTERN);
            String messageId = extractFieldValue(line, MESSAGE_ID_PATTERN);
            String url = extractFieldValue(line, URL_PATTERN);
            String requestBody = extractFieldValue(line, REQUEST_BODY_PATTERN);
            String outputData = extractFieldValue(line, OUTPUT_DATA_PATTERN);
            String rt = extractFieldValue(line, RT_PATTERN);

            if (businessType == null) {
                return null;
            }
            LogInfo logInfo = new LogInfo();
            logInfo.setMessageId(messageId);
            logInfo.setSessionId(sessionId);
            logInfo.setLogTime(toTimestamp(logTime));
            logInfo.setCurrentProcessor(currentProcessor);
            logInfo.setBusinessType(businessType);
            logInfo.setLogId(logId);
            logInfo.setUserId(userId);
            logInfo.setDomainId(domainId);
            logInfo.setSubjectId(subjectId);
            logInfo.setUrl(url);
            logInfo.setRequestBody(requestBody);
            logInfo.setOutputData(outputData);
            logInfo.setRt(rt);
            return logInfo;
        } catch (Exception e) {
            // 解析行时发生异常，返回null
            return null;
        }
    }

    private static String extractFieldValue(String line, Pattern pattern) {
        Matcher matcher = pattern.matcher(line);
        if (matcher.find()) {
            String value = matcher.group(1).trim();
            // 只处理非JSON字段的转义字符，保留JSON字段的原始格式
            if (!isJsonString(value)) {
                // 处理可能存在的转义字符
                value = value.replace("\\\"", "\"");
                value = value.replace("\\n", "\n");
                value = value.replace("\\r", "\r");
                value = value.replace("\\t", "\t");
                // 处理Unicode转义序列
                Pattern unicodePattern = Pattern.compile("\\\\u([0-9a-fA-F]{4})");
                Matcher unicodeMatcher = unicodePattern.matcher(value);
                StringBuffer sb = new StringBuffer();
                while (unicodeMatcher.find()) {
                    char unicodeChar = (char) Integer.parseInt(unicodeMatcher.group(1), 16);
                    unicodeMatcher.appendReplacement(sb, Character.toString(unicodeChar));
                }
                unicodeMatcher.appendTail(sb);
                value = sb.toString();
            }
            return value;
        }
        return null;
    }

    /**
     * 判断字符串是否为JSON格式
     * @param str 待判断的字符串
     * @return 是否为JSON格式
     */
    private static boolean isJsonString(String str) {
        if (str == null || str.length() < 2) {
            return false;
        }
        char firstChar = str.charAt(0);
        char lastChar = str.charAt(str.length() - 1);
        return (firstChar == '{' && lastChar == '}') || (firstChar == '[' && lastChar == ']');
    }

    /**
     * 将 LocalDateTime 转换为毫秒级时间戳（使用系统默认时区）
     * @param dateTime 待转换的时间对象
     * @return 时间戳（自 1970-01-01T00:00:00Z 起的毫秒数）
     */
    public static long toTimestamp(LocalDateTime dateTime) {
        return dateTime.atZone(ZoneId.systemDefault())
                .toInstant()
                .toEpochMilli();
    }

}